import RubikPlay
from tkinter import *
import tkinter.filedialog
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import copy

class StStack:
    def __init__(self):
        self.stack=[]
        
    def push(self,e):
        self.stack.append(e)
        
    def pop(self):
        if(self.isEmpty()):
            return
        popItem=self.stack[-1]
        self.stack=self.stack[:-1]
        return popItem
    
    def isEmpty(self):
        if(len(self.stack)==0):
            return True
        return False
    
    def getSize(self):
        return len(self.stack)
    
    def peek(self):
        return self.stack[-1]
##############################################函数
def upDate():
    global M,canvas,root
    fig,ax=M.getImg()
    canvas = FigureCanvasTkAgg(fig, root)
    canvas.get_tk_widget().grid(row=4,column=0,columnspan=4)

def rotate(M,opList,direct): #操作魔方
    global canvas,stUndo,stRedo
    stUndo.push(copy.deepcopy(M.getState()))
    stRedo=StStack()
    M.rotate(opList,direct)
    upDate()
    #fig,ax=M.getImg()
    #canvas = FigureCanvasTkAgg(fig, root)
    #canvas.get_tk_widget().grid(row=4,column=0,columnspan=4)

def viewImage(M): #显示3d图
    fig,ax=M.getImg()
    fig.show()
    
def Destroy(): #关闭
    global root
    root.destroy()
    
def Load(): #读取文件
    global stUndo,stRedo
    stUndo=StStack()
    stRedo=StStack()
    path_=tkinter.filedialog.askopenfilename()
    extend=path_.split('.')[-1]
    if(extend!="rubik"):
        return
    global M
    global canvas
    M.loadFile(path_)
    fig,ax=M.getImg()
    canvas = FigureCanvasTkAgg(fig, root)
    canvas.get_tk_widget().grid(row=4,column=0,columnspan=4)
    
def Save(): #保存文件
    global M
    path_=tkinter.filedialog.asksaveasfilename()
    M.writeAsFile(path_+".rubik")
    
def Undo(): #撤销
    global canvas,stUndo,M,stRedo
    if(not stUndo.isEmpty()):
        stRedo.push(M.getState())
        M.setState(stUndo.pop())
        upDate()
    
def Redo(): #重做
    global stUndo,M,stRedo
    if(not stRedo.isEmpty()):
        stUndo.push(M.getState())
        M.setState(stRedo.pop())
        upDate()
##############################################
M=RubikPlay.RubikInteraction()
fig,ax=M.getImg()

root=Tk()
root.title("Rubik Game")
stUndo=StStack()
stRedo=StStack()

canvas = FigureCanvasTkAgg(fig, root)
canvas.get_tk_widget().grid(row=4,column=0,columnspan=4)
##############################################按钮
b=Button(root, text='x=1[1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[1,0,0],1))
b.grid(row=0,column=0)

b=Button(root, text='x=3[1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[3,0,0],1))
b.grid(row=0,column=2)

b=Button(root, text='y=1[1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,1,0],1))
b.grid(row=1,column=0)

b=Button(root, text='y=3[1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,3,0],1))
b.grid(row=1,column=2)

b=Button(root, text='z=1[1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,0,1],1))
b.grid(row=2,column=0)

b=Button(root, text='z=3[1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,0,3],1))
b.grid(row=2,column=2)

b=Button(root, text='x=1[-1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[1,0,0],-1))
b.grid(row=0,column=1)

b=Button(root, text='x=3[-1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[3,0,0],-1))
b.grid(row=0,column=3)

b=Button(root, text='y=1[-1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,1,0],-1))
b.grid(row=1,column=1)

b=Button(root, text='y=3[-1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,3,0],-1))
b.grid(row=1,column=3)

b=Button(root, text='z=1[-1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,0,1],-1))
b.grid(row=2,column=1)

b=Button(root, text='z=3[-1]', font=('Arial', 12), width=10, height=1, command=lambda:rotate(M,[0,0,3],-1))
b.grid(row=2,column=3)

b=Button(root, text='View Image', font=('Arial', 12), width=10, height=1, command=lambda:viewImage(M))
b.grid(row=3,column=0)

b=Button(root, text='Quit', font=('Arial', 12), width=10, height=1, command=lambda:Destroy())
b.grid(row=3,column=3)

b=Button(root, text='←', font=('Arial', 12), width=10, height=1, command=lambda:Undo())
b.grid(row=3,column=1)

b=Button(root, text='→', font=('Arial', 12), width=10, height=1, command=lambda:Redo())
b.grid(row=3,column=2)
##############################################
##############################################菜单
menubar=Menu(root)
filemenu=Menu(menubar, tearoff=0)
menubar.add_cascade(label='文件',menu=filemenu)
filemenu.add_command(label='打开', command=lambda:Load())
filemenu.add_command(label='保存', command=lambda:Save())
##############################################
root.config(menu=menubar)
root.mainloop()
